package com.hongyun.tms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.hongyun.tms.common.PageResponseDto;
import com.hongyun.tms.common.constants.DefaultCreateByConstant;
import com.hongyun.tms.common.dto.crewcert.CrewCertQueryDto;
import com.hongyun.tms.common.dto.crewcert.CrewCertSaveReqDto;
import com.hongyun.tms.common.utils.AttachUtil;
import com.hongyun.tms.common.utils.DateUtils;
import com.hongyun.tms.common.utils.MapperingUtils;
import com.hongyun.tms.common.vo.CrewCertVO;
import com.hongyun.tms.entity.CrewCert;
import com.hongyun.tms.entity.SysFileBusiness;
import com.hongyun.tms.mapper.CrewCertMapper;
import com.hongyun.tms.service.ICrewCertService;
import com.hongyun.tms.service.ISysFileBusinessService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 船员证书 服务实现类
 * </p>
 *
 * @author liPeng
 * @since 2024-06-25
 */
@Service
public class CrewCertServiceImpl extends ServiceImpl<CrewCertMapper, CrewCert> implements ICrewCertService {
    @Resource
    private ISysFileBusinessService fileBusinessService;

    @Resource
    private AttachUtil attachUtil;

    @Override
    public PageResponseDto<CrewCertVO> pageList(CrewCertQueryDto dto) {
//        if (dto.getCrewId() == null) {
//            throw new BusinessRuntimeException(Response.BizCode.CREW_ID_NOT_NULL, Response.BizCode.CREW_ID_NOT_NULL.getComment());
//        }
        Page<CrewCert> page = new Page<>(dto.getStartPage(), dto.getPageSize());
        baseMapper.selectPage(page, new LambdaQueryWrapper<CrewCert>()
                .eq(dto.getCrewId() != null, CrewCert::getCrewId, dto.getCrewId())
//                .like(StringUtils.isNotBlank(dto.getCrewName()), CrewCert::getCrewName, dto.getCrewName())
                .like(StringUtils.isNotBlank(dto.getCertName()), CrewCert::getCertName, dto.getCertName())
                .lt(dto.getExpireFlag() != null && dto.getExpireFlag() == 0,  CrewCert::getEndDate, LocalDate.now())
                .ge(dto.getExpireFlag() != null && dto.getExpireFlag() == 1, CrewCert::getEndDate, LocalDate.now())

        );


        PageResponseDto<CrewCertVO> pageResponseDto = new PageResponseDto(page, CrewCertVO.class);
//        // 提取证书ID列表
//        List<Long> idList = pageResponseDto.getRecords().stream().map(CrewCertVO::getId).collect(Collectors.toList());
//
//        // 获取业务附件关联数据
//        List<SysFileBusiness> businessList = CollectionUtils.isEmpty(idList) ? Collections.emptyList() :
//                fileBusinessService.list(new LambdaQueryWrapper<SysFileBusiness>().in(SysFileBusiness::getBusinessId, idList));
//
//        // 提取文件ID集合
//        Set<Long> fileIdSet = businessList.stream().map(SysFileBusiness::getFileId).collect(Collectors.toSet());
//
//        // 业务ID映射到附件列表的映射
//        Map<Long, List<SysFileBusiness>> businessMapByBusId = businessList.stream().collect(Collectors.groupingBy(SysFileBusiness::getBusinessId));
//
//        // 获取文件详细信息
//        List<SysFileDTO> files = fileService.listByIds(new ArrayList<>(fileIdSet));
//
//        // 为每个证书VO设置附件列表
//        for (CrewCertVO vo : pageResponseDto.getRecords()) {
//            List<CrewCertVO.Attach> attachList = Lists.newArrayList();
//
//            // 查找对应业务ID的附件
//            for (Long busId : businessMapByBusId.keySet()) {
//                if (busId.equals(vo.getId())) {
//                    List<SysFileBusiness> fileBusinesses = businessMapByBusId.get(busId);
//                    List<Long> relationFileIdList = fileBusinesses.stream().map(SysFileBusiness::getFileId).collect(Collectors.toList());
//
//                    // 过滤文件列表
//                    List<SysFileDTO> filterFiles = files.stream().filter(file -> relationFileIdList.contains(file.getId())).collect(Collectors.toList());
//
//                    // 构建附件列表
//                    for (SysFileDTO filterFile : filterFiles) {
//                        CrewCertVO.Attach attach = CrewCertVO.Attach
//                                .builder()
//                                .id(filterFile.getId().toString())
//                                .url(minIoConfig.getMinioUrl() + "/minio/" + filterFile.getFileBucket() + "/" + filterFile.getFilePath() + filterFile.getFileSaveName())
//                                .build();
//                        attachList.add(attach);
//                    }
//                }
//            }
//            vo.setAttachList(attachList);
//        }

        //设置过期标识
        for (CrewCertVO record : pageResponseDto.getRecords()) {
            boolean noExpire = LocalDate.now().isBefore(record.getEndDate());
            record.setExpireFlag(noExpire ? 1 : 0);
        }
        return pageResponseDto;
    }

    @Override
    public CrewCertVO getOneById(Long id) {
        CrewCert crewCert = getById(id);
        CrewCertVO vo = MapperingUtils.copyProperties(crewCert, CrewCertVO.class);

        //设置附件
        List<CrewCertVO.Attach> attachList = attachUtil.getAttachList(
                vo.getId(), CrewCertVO.Attach.class
        );
        vo.setAttachList(attachList);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdate(CrewCertSaveReqDto dto) {
        // 将 DTO 转换为实体类
        CrewCert cert = MapperingUtils.copyProperties(dto, CrewCert.class);

        // 设置通用属性
        LocalDateTime now = LocalDateTime.now();
        cert.setUpdateTime(now);
        cert.setUpdateBy(DefaultCreateByConstant.userId);
        cert.setUpdateByName(DefaultCreateByConstant.userId.toString());
        cert.setBeginDate(DateUtils.str2LocalDate(dto.getBeginDate()));
        cert.setEndDate(DateUtils.str2LocalDate(dto.getEndDate()));

        // 如果 ID 为空，执行插入操作
        if (dto.getId() == null) {
            handleInsert(cert, dto, now);
        } else {
            handleUpdate(cert);
        }
    }

    private void handleInsert(CrewCert cert, CrewCertSaveReqDto dto, LocalDateTime now) {
        // 生成新 ID 并设置相关属性
        long id = IdWorker.getId();
        cert.setId(id);
        cert.setCreateTime(now);
        cert.setCreateBy(dto.getCrewId());
        cert.setCreateByName(DefaultCreateByConstant.userId.toString());
        //保存实体
        save(cert);
        if (StringUtils.isNotBlank(cert.getAttachUrl())) {
        //将附件关联插入到业务附件表
        String[] imgIdArr = cert.getAttachUrl().split(",");
        List<SysFileBusiness> relationList = Lists.newArrayList();
        for (String imgId : imgIdArr) {
            SysFileBusiness build = SysFileBusiness
                    .builder()
                    .id(IdWorker.getId())
                    .businessId(id)
//                    .creator(AuthUtil.getUserId())
                    .fileId(Long.valueOf(imgId))
//                    .modifier(AuthUtil.getUserId())
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
//                    .modifier(AuthUtil.getUserId())
                    .build();
            relationList.add(build);
        }
        fileBusinessService.saveBatch(relationList);
        }
    }

    private void handleUpdate(CrewCert cert) {
        // 更新实体
        updateById(cert);

        // 移除当前证件之前存在的附件，无论 attachUrl 是否为空
        fileBusinessService.remove(new LambdaQueryWrapper<SysFileBusiness>().eq(SysFileBusiness::getBusinessId, cert.getId()));

        // 如果 attachUrl 不为空，则处理新的附件关联
        if (StringUtils.isNotBlank(cert.getAttachUrl())) {
            String[] imgIdArr = cert.getAttachUrl().split(",");
            List<SysFileBusiness> relationList = Lists.newArrayList();
            for (String imgId : imgIdArr) {
                SysFileBusiness build = SysFileBusiness
                        .builder()
                        .id(IdWorker.getId())
                        .businessId(cert.getId())
//                        .creator(AuthUtil.getUserId())
                        .fileId(Long.valueOf(imgId))
//                        .modifier(AuthUtil.getUserId())
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build();
                relationList.add(build);
            }
            fileBusinessService.saveBatch(relationList);
        }
    }

}
